Flutter练习(五) 您所在的位置:网站首页 flutter tabbar 自定义样式 Flutter练习(五)

Flutter练习(五)

2023-07-22 05:14| 来源: 网络整理| 查看: 265

前言

之前做了个仿掘金的flutter程序,代码已经放到了guthub上去,由于一些个人问题,有较长一段时间没有更新flutter的相关文章,本篇将会介绍如何构建tabbar,让tabbar有用滑动切屏的效果

要构建tabbar的滑动切屏,主要有以下几点:

入口文件的配置 页面的一个整体构造 上:标题栏组件 中:页面跳转、滑动渲染中间部分的页面 下:tabbar的渲染及相关交互逻辑 入口文件的配置

main.dart 文件

该文件主要进行一些数据、缓存的初始化,以及启动页面时的页面跳转至什么地方

有些应用还需判断用户是否已经登陆,并跳转至登陆页面,这里由于时一个博客网站,并把入口跳登陆的一些逻辑删除了。

import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_application/config/storage_manager.dart'; import 'package:flutter_application/config/theme.dart'; import 'package:flutter_application/root/root_page.dart'; import 'package:flutter_application/route/route.dart'; import 'mine.dart'; void main() async{ FlutterError.onError = (FlutterErrorDetails details) { FlutterError.dumpErrorToConsole(details); if (kReleaseMode) exit(1); }; // 确保初始化 WidgetsFlutterBinding.ensureInitialized(); // 缓存初始化 await StorageManager.init(); runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO判断是否登陆 return MaterialApp( navigatorKey: navGk, title: 'Flutter Blog 练习', theme: ThemeData( scaffoldBackgroundColor: bgColor, hintColor: Colors.grey.withOpacity(0.3), splashColor: Colors.transparent, canvasColor: Colors.transparent ), debugShowCheckedModeBanner: false, routes: { '/': (context) { return RootPage(); } }, ); } } 页面整体的构建

一般情况,tab页面主要分为了以下三部分

上:标题栏组件 中:页面跳转、滑动渲染中间部分的页面 下:tabbar的渲染及相关交互逻辑 标题栏组件

common_bar.dart

该组件主要配置了标题、交互图标、主题色及一些相关样式等的部分

交互逻辑中主要实现的点击的交互效果

import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_application/config/theme.dart'; class CommonBar extends StatelessWidget implements PreferredSizeWidget { final String title; final bool showShadow; final List? rightDMActions; final Color backgroundColor; final Color mainColor; final Widget? titleW; final Widget? leadingW; final PreferredSizeWidget? bottom; final String leadingImg; CommonBar( {this.title = '', this.showShadow = false, this.rightDMActions, this.backgroundColor = appBarColor, this.mainColor = Colors.white, this.titleW, this.leadingW, this.bottom, this.leadingImg = ''}); // tabBar 左侧图标及相关操作逻辑 Widget? leading(BuildContext context) { bool isShow = Navigator.canPop(context); if (isShow) { return new InkWell( child: new Container( width: 15, height: 28, child: leadingImg != '' ? new Image.asset(leadingImg) : new Icon(CupertinoIcons.back, color: mainColor), ), onTap: () { if (Navigator.canPop(context)) { FocusScope.of(context).requestFocus(new FocusNode()); Navigator.pop(context); } }, ); } else { return null; } } @override Widget build(BuildContext context) { // 封装appBar Widget appBar = new AppBar( title: titleW != null ? titleW : new Text( title, style: new TextStyle( color: mainColor, fontSize: 16.0, fontWeight: FontWeight.w600, ), ), backgroundColor: backgroundColor, elevation: 0, brightness: Brightness.light, leading: leadingW ?? leading(context), centerTitle: true, actions: rightDMActions ?? [new Center()], bottom: bottom ?? null, ); return showShadow ? new Container( decoration: BoxDecoration( border: Border( bottom: new BorderSide(color: Colors.grey, width: 0.5))), child: appBar, ) : appBar; } @override // TODO: implement preferredSize Size get preferredSize => new Size(100, 50); } 页面跳转及滑动的效果

root_tabbar.dart

滑动的主要是先判断应用环境为Android还是IOS

Android的滑动方法:ClampingScrollPhysics()

IOS的滑动方法:NeverScrollableScrollPhysics()

然后根据索引值切换相关tabbarModel数组的相关页面

import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_application/config/theme.dart'; import 'package:flutter_application/pages/common/bar/common_bar.dart'; class RootTabBar extends StatefulWidget { final List pages; final int currentIndex; RootTabBar({required this.pages, this.currentIndex = 0}); State createState() => new RootTabBarState(); } class RootTabBarState extends State { List pages = []; late int currentIndex; late PageController pageController; @override void initState() { super.initState(); currentIndex = widget.currentIndex; pageController = PageController(initialPage: currentIndex); widget.pages.forEach((element) { TabBarModel model = element; pages.add(new BottomNavigationBarItem( icon: model.icon, activeIcon: model.selectIcon, title: new Text( model.title!, style: new TextStyle(fontSize: 12.0), ))); }); } @override Widget build(BuildContext context) { // if(pageController) { pageController = PageController(initialPage: currentIndex); // } final BottomNavigationBar bottomNavigationBar = new BottomNavigationBar( items: pages, type: BottomNavigationBarType.fixed, currentIndex: currentIndex, onTap: (int index) { setState(() { currentIndex = index; pageController.jumpToPage(currentIndex); }); }, unselectedFontSize: 12.0, selectedFontSize: 12.0, selectedItemColor: primaryColor, elevation: 0, ); var appBar = new CommonBar( title: widget.pages[currentIndex].title, showShadow: false); return Scaffold( resizeToAvoidBottomInset: false, // 键盘弹起引起的挤压问题 // 底部tab栏 bottomNavigationBar: new Theme( data: new ThemeData( canvasColor: Colors.grey[50], highlightColor: Colors.transparent, splashColor: Colors.transparent), child: new Container( decoration: BoxDecoration( border: Border(top: BorderSide(color: lineColor, width: 0.2))), child: bottomNavigationBar, )), // 头部tab栏 appBar: appBar, // body body: new PageView.builder( itemBuilder: (BuildContext context, int index) => widget.pages[index].page, controller: pageController, itemCount: pages.length, physics: Platform.isAndroid ? new ClampingScrollPhysics() : new NeverScrollableScrollPhysics(), onPageChanged: (int index) => setState(() => currentIndex = index), ), ); } } class TabBarModel { final String? title; final Widget icon; final Widget? selectIcon; final Widget? page; TabBarModel({this.title, required this.icon, this.selectIcon, this.page}); } tabbar的相关页面配置

root_page.dart

import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_application/config/theme.dart'; import 'package:flutter_application/pages/tabbar/Index.dart'; import 'package:flutter_application/pages/tabbar/mine.dart'; import 'package:flutter_application/pages/tabbar/boil.dart'; import 'package:flutter_application/root/root_tabbar.dart'; import 'package:flutter_application/route/route.dart'; class RootPage extends StatefulWidget { _RootPageState createState() => _RootPageState(); } class _RootPageState extends State { @override Widget build(BuildContext context) { List pages = [ new TabBarModel( title: "首页", icon: const Icon(IconData(0xe7c0,fontFamily: 'MyIcons')), selectIcon: const Icon(IconData(0xe7c0,fontFamily: 'MyIcons'),color: primaryColor,), page: new IndexPage()), // new TabBarModel( // title: '沸点', // icon: new LoadImage("assets/images/tab_order_normal_icon.png"), // selectIcon: // new LoadImage("assets/images/tab_order_selected_icon.png"), // page: new BoilPage()), new TabBarModel( title: '发现', icon: const Icon(IconData(0xe8d6,fontFamily: 'MyIcons')), selectIcon:const Icon(IconData(0xe8d6,fontFamily: 'MyIcons'),color: primaryColor,), page: new BoilPage()), // new TabBarModel( // title: '小册', // icon: new LoadImage("assets/images/tab_order_normal_icon.png"), // selectIcon: // new LoadImage("assets/images/tab_order_selected_icon.png"), // page: new BoilPage()), new TabBarModel( title: '我的', icon: const Icon(IconData(0xe613,fontFamily: 'MyIcons')), selectIcon:const Icon(IconData(0xe613,fontFamily: 'MyIcons'),color: primaryColor,), page: new MinePage()) ]; return new Scaffold( key: scaffoldGK, body: new RootTabBar(pages: pages, currentIndex: 0), ); } } class LoadImage extends StatelessWidget { final String img; LoadImage(this.img); @override Widget build(BuildContext context) { return new Container( margin: EdgeInsets.only(bottom: 2.0), child: new Image.asset(img, fit: BoxFit.cover, gaplessPlayback: true), ); } } 滑动切屏效果



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有